package org.parallelCompiler.modifyCF.logic;

import takatuka.classreader.dataObjs.*;
import takatuka.classreader.dataObjs.attribute.*;
import takatuka.classreader.dataObjs.constantPool.StringInfo;
import takatuka.classreader.dataObjs.constantPool.UTF8Info;
import takatuka.classreader.logic.factory.*;
import takatuka.optimizer.cpGlobalization.logic.util.*;

/**
 *
 * @author aslam
 */
public class Util {

    private static final FactoryPlaceholder placeHolder = FactoryPlaceholder.getInstanceOf();
    private static final FactoryFacade facade = placeHolder.getFactory();

    public static Instruction createInstr(CodeAtt codeAtt, int opCode) throws Exception {
        return createInstr(codeAtt, opCode, facade.createUn().trim(0));
    }

    public static Instruction createInstr(CodeAtt codeAtt, int opCode, Un operands) throws Exception {
        return facade.createInstruction(opCode, operands, codeAtt);
    }

    public static MethodInfo findMethod(ClassFile classFile, String methodName) {
        Oracle oracle = Oracle.getInstanceOf();
        MethodInfoController mController = classFile.getMethodInfoController();
        for (int index = 0; index < mController.getCurrentSize(); index++) {
            MethodInfo methodInfo = (MethodInfo) mController.get(index);
            int nameIndex = methodInfo.getNameIndex().intValueUnsigned();
            String candidateName = oracle.getUTF8(nameIndex, classFile.getConstantPool());
            if (candidateName.equals(methodName)) {
                return methodInfo;
            }
        }
        return null;
    }

    public static int addUTF8InCP(MultiplePoolsFacade cp, String stringToBeAdded) throws Exception {
        Oracle oracle = Oracle.getInstanceOf();
        int ret = oracle.getUTF8InfoIndex(stringToBeAdded);
        if (ret != -1) {
            return ret;
        }
        UTF8Info utf8 = facade.createUTF8Info();
        byte[] byteUTF8 = stringToBeAdded.getBytes("UTF-8");
        Un unUTF8 = facade.createUn(byteUTF8);
        utf8.setBytes(unUTF8);
        utf8.setLength(unUTF8);
        return cp.add(utf8, -1);
    }

    public static int addStringInfoInCP(MultiplePoolsFacade cp, int utf8Index) throws Exception {
        StringInfo stringInfo = facade.createStringInfo();
        stringInfo.setIndex(utf8Index);
        return cp.add(stringInfo, -1);
    }

    public static int addStringInfoInCP(MultiplePoolsFacade cp, String stringToBeAdded) throws Exception {
        int cpIndex = addUTF8InCP(cp, stringToBeAdded);
        return addStringInfoInCP(cp, cpIndex);
    }
}
